using System;
using System.Collections.Generic;
using System.Text;

namespace WOWEquipOptimizer.Warlock
{
    class Affliction : CasterDD
    {
        public Affliction()
            : base()
        {
            m_Base = new List<Attribute>();
            m_Base.Add(new Attribute(AttributeName.Mana, 3000));
            m_Base.Add(new Attribute(AttributeName.Health, 4300));
            m_Base.Add(new Attribute(AttributeName.Stamina, 165));
            m_Base.Add(new Attribute(AttributeName.Intellect, 130));
            m_Base.Add(new Attribute(AttributeName.Spirit, 122));
            m_Base.Add(new Attribute(AttributeName.CritSpellRating, 3.3f * CritSpellRating));
            // talents
            m_Base.Add(new Attribute(AttributeName.SpellDamage, 100));           
            foreach (Attribute attr in m_Base)
            {
                handleAttribute(attr);
            }
            Buff imp = new Buff("Imp", new List<Attribute>());
            imp.Attributes.Add(new Attribute(AttributeName.Stamina, 64));
            Buffs.Add(imp);

        }
        // mana, int, spirit, shadowspelldmg, firespelldmg, spellcrit, spellhit, spellhaste, mp5,hp5, health
        public override float evaluateTF()
        {
            float runtime = 600;
            float mana = m_Equip[AttributeName.Mana];
            float shadowdmg = m_Equip[AttributeName.ShadowSpellDamage];
            float firedmg = m_Equip[AttributeName.FireSpellDamage];
            float crit = m_Equip[AttributeName.CritSpellRating] / CritSpellRating;
            float hit = m_Equip[AttributeName.HitSpellRating] / HitSpellRating;
            float haste = m_Equip[AttributeName.HasteSpellRating] / HasteSpellRating;
            float mp5 = m_Equip[AttributeName.MP5];
            float hp5 = m_Equip[AttributeName.HP5];
            float health = m_Equip[AttributeName.Health];
            float affhit = Math.Min(99, 83 + hit + 10f);
            hit = Math.Min(99, 83 + hit);
            float time = runtime;
            float corruptionmana = 340;
            float corruptiondmg = 900 + 1.05f * 1.36f * 0.92f * shadowdmg;
            float destcrit = (crit+5)/100;
            float nonimpsb = (float) Math.Pow(destcrit, 4f);
            float shadowdmgmod = 1 + (nonimpsb * destcrit * 0.5f + (1 - destcrit) * nonimpsb * 0 + destcrit * (1 - nonimpsb) * 0.8f + (1 - nonimpsb) * (1 - destcrit) * 0.2f);
            float shadowboltmana = 420;
            float shadowboltdmg = (hit / 100f) * (1 + 0.5f * destcrit) * (572 + (6 / 7f) * shadowdmg);
            float lifetap = 580 + 0.8f * shadowdmg;
            float immolatedmg = (hit / 100f) * ((1 + 0.5f * destcrit) * (327 + 0.20f * firedmg) + (615 + 0.65f * firedmg));
            float immolatemana = 445;
            float uadmg = 1050 + 1.2f * shadowdmg;
            float uamana = 400;
            float coamana = 265;
            float coadmg = 1356 + 1.2f * shadowdmg;
            // coa-ua-corr-immo-sb-sb-sb-sb-dp-lt
            float rotdmg = (affhit / 100f) * 1.1f * (24 / 18f * corruptiondmg + 24 / 18f * uadmg + 1.1f * coadmg) + 1.1f * (shadowdmgmod * 4 * shadowboltdmg) + 24 / 15f * immolatedmg;
            float rottime = 24;
            float rotmana = Math.Max(shadowboltmana * 4 + corruptionmana + uamana + coamana + immolatemana - lifetap - mp5 / 5 * 24f - 700, 1);
            float rotcount = Math.Min(mana / rotmana, time / rottime);
            float finaldps = 1.1f * (rotdmg * rotcount) / runtime; //coe&cos
            return CondFactor * finaldps;
        }
        // mana, int, spirit, shadowspell, firespelldmg, spellcrit, spellhit, spellhaste, mp5,health
        public override void handleAttribute(Attribute attr)
        {
            switch (attr.Type)
            {
                case AttributeName.Intellect:
                    m_Equip[AttributeName.Mana] += attr.Value * (HasBlessingOfKings ? 1.1f : 1.0f) * 15;
                    m_Equip[attr.Type] += attr.Value * (HasBlessingOfKings ? 1.1f : 1.0f);
                    m_Equip[AttributeName.CritSpellRating] += (attr.Value * (HasBlessingOfKings ? 1.1f : 1.0f) / 80) * CritSpellRating;
                    break;
                case AttributeName.SpellDamage:
                    m_Equip[AttributeName.FireSpellDamage] += attr.Value;
                    m_Equip[AttributeName.ShadowSpellDamage] += attr.Value;
                    break;
                default:
                    base.handleAttribute(attr);
                    break;
            }
        }
        public override List<Item> filterEquip(List<Item> input)
        {
            input = base.filterEquip(input);
            List<Item> retval = new List<Item>();
            ItemBlacklist.Add("Atiesh, Greatstaff of the Guardian");
            ItemBlacklist.Add("Violet Signet");
            foreach (Item item in input)
            {
                if ((item.AllowableClasses & CharacterClass.Warlock) == 0) continue;
                if (item.GetType() == typeof(Weapon))
                {
                    Weapon weapon = (Weapon)item;
                    if (weapon.WeaponSlot == WeaponSlot.Ranged)
                    {
                        if (weapon.Type != WeaponType.Wand) continue;
                    }
                    if (weapon.Type == WeaponType.Axe || weapon.Type == WeaponType.Mace) continue;
                    if (weapon.TwoHand && weapon.Type != WeaponType.Staff) continue;
                }
                else if (item.GetType() == typeof(Armor))
                {
                    Armor armor = (Armor)item;
                    if ((armor.Type & ArmorProficiency.Cloth) == 0) continue;
                }
                if (SetBlacklist.Contains(item.Set.Name)) continue;
                if (ItemBlacklist.Contains(item.Name)) continue;
                retval.Add(item);
            }
            return handleWhiteList(retval);
        }
        public override bool evaluateBuild(int[] build)
        {
            if (build[0] >= 41 && build[2] >= 15)
            {
                return true;
            }
            else return false;
        }
        public override string[] getAttributes()
        {
            return new string[] { "Mana", "Intellect", "Spirit", "ShadowSpellDamage", "FireSpellDamage", "CritSpellRating", "HitSpellRating", "HasteSpellRating", "MP5", "HP5", "Health" };
        }
    }
}
